#pragma once
#include <string>
#include <cmath>

namespace test_thingey {

	using namespace System;
	using namespace System::ComponentModel;
	using namespace System::Collections;
	using namespace System::Windows::Forms;
	using namespace System::Data;
	using namespace System::Drawing;
	using namespace System::Diagnostics;

	double Robo_angle = 0.0; //the angle of the robot picture
	int mouse_x;
	int mouse_y;
	int mx[100]; //saves 100 different mouse points
	int my[100]; //saves 100 different mouse points
	int linecount; //count lines, current line
    
	/// <summary>
	/// Summary for Form1
	///
	/// WARNING: If you change the name of this class, you will need to change the
	///          'Resource File Name' property for the managed resource compiler tool
	///          associated with all .resx files this class depends on.  Otherwise,
	///          the designers will not be able to interact properly with localized
	///          resources associated with this form.
	/// </summary>
	public ref class Form1 : public System::Windows::Forms::Form
	{
	public:
		Form1(void)
		{
			InitializeComponent();
			//
			//TODO: Add the constructor code here
			//
		}

	protected:
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		~Form1()
		{
			if (components)
			{
				delete components;
			}
		}
	private: System::Windows::Forms::TextBox^  textBox1;
	protected: 
	private: System::Windows::Forms::TextBox^  textBox2;


	private: System::Windows::Forms::TextBox^  textBox3;
	private: System::Windows::Forms::Label^  label1;
	private: System::Windows::Forms::TextBox^  textBox4;


	private: System::Windows::Forms::Label^  label2;

	private: System::Windows::Forms::ListBox^  listBox_line_measurements;
	private: System::Windows::Forms::Button^  button_clear_lines;
	private: System::Windows::Forms::Button^  Angle_button;
	private: System::Windows::Forms::Button^  Button_delete_last;
	private: System::Windows::Forms::RadioButton^  radioButton_angle0;
	private: System::Windows::Forms::RadioButton^  radioButton_angle30;
	private: System::Windows::Forms::RadioButton^  radioButton_angle60;
	private: System::Windows::Forms::RadioButton^  radioButton_angle90;





	private:
		/// <summary>
		/// Required designer variable.
		/// </summary>
		System::ComponentModel::Container ^components;

#pragma region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		void InitializeComponent(void)
		{
			System::ComponentModel::ComponentResourceManager^  resources = (gcnew System::ComponentModel::ComponentResourceManager(Form1::typeid));
			this->textBox1 = (gcnew System::Windows::Forms::TextBox());
			this->textBox2 = (gcnew System::Windows::Forms::TextBox());
			this->textBox3 = (gcnew System::Windows::Forms::TextBox());
			this->label1 = (gcnew System::Windows::Forms::Label());
			this->textBox4 = (gcnew System::Windows::Forms::TextBox());
			this->label2 = (gcnew System::Windows::Forms::Label());
			this->listBox_line_measurements = (gcnew System::Windows::Forms::ListBox());
			this->button_clear_lines = (gcnew System::Windows::Forms::Button());
			this->Angle_button = (gcnew System::Windows::Forms::Button());
			this->Button_delete_last = (gcnew System::Windows::Forms::Button());
			this->radioButton_angle0 = (gcnew System::Windows::Forms::RadioButton());
			this->radioButton_angle30 = (gcnew System::Windows::Forms::RadioButton());
			this->radioButton_angle60 = (gcnew System::Windows::Forms::RadioButton());
			this->radioButton_angle90 = (gcnew System::Windows::Forms::RadioButton());
			this->SuspendLayout();
			// 
			// textBox1
			// 
			this->textBox1->Location = System::Drawing::Point(15, 488);
			this->textBox1->Name = L"textBox1";
			this->textBox1->Size = System::Drawing::Size(176, 20);
			this->textBox1->TabIndex = 0;
			// 
			// textBox2
			// 
			this->textBox2->Location = System::Drawing::Point(216, 488);
			this->textBox2->Name = L"textBox2";
			this->textBox2->Size = System::Drawing::Size(162, 20);
			this->textBox2->TabIndex = 1;
			// 
			// textBox3
			// 
			this->textBox3->Location = System::Drawing::Point(422, 465);
			this->textBox3->Name = L"textBox3";
			this->textBox3->Size = System::Drawing::Size(73, 20);
			this->textBox3->TabIndex = 3;
			this->textBox3->Text = L"0.099009901";
			// 
			// label1
			// 
			this->label1->AutoSize = true;
			this->label1->Location = System::Drawing::Point(343, 468);
			this->label1->Name = L"label1";
			this->label1->Size = System::Drawing::Size(73, 13);
			this->label1->TabIndex = 4;
			this->label1->Text = L"Revs per inch";
			// 
			// textBox4
			// 
			this->textBox4->Location = System::Drawing::Point(239, 465);
			this->textBox4->Name = L"textBox4";
			this->textBox4->Size = System::Drawing::Size(98, 20);
			this->textBox4->TabIndex = 5;
			this->textBox4->Text = L"0.009910034";
			this->textBox4->TextChanged += gcnew System::EventHandler(this, &Form1::textBox4_TextChanged);
			// 
			// label2
			// 
			this->label2->AutoSize = true;
			this->label2->Location = System::Drawing::Point(156, 468);
			this->label2->Name = L"label2";
			this->label2->Size = System::Drawing::Size(75, 13);
			this->label2->TabIndex = 8;
			this->label2->Text = L"Revs per Pixel";
			// 
			// listBox_line_measurements
			// 
			this->listBox_line_measurements->FormattingEnabled = true;
			this->listBox_line_measurements->Location = System::Drawing::Point(925, 9);
			this->listBox_line_measurements->Name = L"listBox_line_measurements";
			this->listBox_line_measurements->Size = System::Drawing::Size(155, 433);
			this->listBox_line_measurements->TabIndex = 10;
			this->listBox_line_measurements->SelectedIndexChanged += gcnew System::EventHandler(this, &Form1::listBox_line_measurements_SelectedIndexChanged);
			// 
			// button_clear_lines
			// 
			this->button_clear_lines->Location = System::Drawing::Point(501, 448);
			this->button_clear_lines->Name = L"button_clear_lines";
			this->button_clear_lines->Size = System::Drawing::Size(179, 59);
			this->button_clear_lines->TabIndex = 11;
			this->button_clear_lines->Text = L"Clear Lines";
			this->button_clear_lines->UseVisualStyleBackColor = true;
			this->button_clear_lines->Click += gcnew System::EventHandler(this, &Form1::button_clear_lines_Click);
			// 
			// Angle_button
			// 
			this->Angle_button->Location = System::Drawing::Point(15, 457);
			this->Angle_button->Name = L"Angle_button";
			this->Angle_button->Size = System::Drawing::Size(135, 28);
			this->Angle_button->TabIndex = 12;
			this->Angle_button->Text = L"Angle";
			this->Angle_button->UseVisualStyleBackColor = true;
			this->Angle_button->Click += gcnew System::EventHandler(this, &Form1::button1_Click_1);
			// 
			// Button_delete_last
			// 
			this->Button_delete_last->Location = System::Drawing::Point(687, 448);
			this->Button_delete_last->Name = L"Button_delete_last";
			this->Button_delete_last->Size = System::Drawing::Size(198, 59);
			this->Button_delete_last->TabIndex = 13;
			this->Button_delete_last->Text = L"Delete Last Line";
			this->Button_delete_last->UseVisualStyleBackColor = true;
			this->Button_delete_last->Click += gcnew System::EventHandler(this, &Form1::Button_delete_last_Click);
			// 
			// radioButton_angle0
			// 
			this->radioButton_angle0->AutoSize = true;
			this->radioButton_angle0->Location = System::Drawing::Point(906, 457);
			this->radioButton_angle0->Name = L"radioButton_angle0";
			this->radioButton_angle0->Size = System::Drawing::Size(72, 17);
			this->radioButton_angle0->TabIndex = 14;
			this->radioButton_angle0->TabStop = true;
			this->radioButton_angle0->Text = L"0 degrees";
			this->radioButton_angle0->UseVisualStyleBackColor = true;
			this->radioButton_angle0->CheckedChanged += gcnew System::EventHandler(this, &Form1::radioButton_angle0_CheckedChanged);
			// 
			// radioButton_angle30
			// 
			this->radioButton_angle30->AutoSize = true;
			this->radioButton_angle30->Location = System::Drawing::Point(998, 457);
			this->radioButton_angle30->Name = L"radioButton_angle30";
			this->radioButton_angle30->Size = System::Drawing::Size(78, 17);
			this->radioButton_angle30->TabIndex = 15;
			this->radioButton_angle30->TabStop = true;
			this->radioButton_angle30->Text = L"30 degrees";
			this->radioButton_angle30->UseVisualStyleBackColor = true;
			this->radioButton_angle30->CheckedChanged += gcnew System::EventHandler(this, &Form1::radioButton_angle30_CheckedChanged);
			// 
			// radioButton_angle60
			// 
			this->radioButton_angle60->AutoSize = true;
			this->radioButton_angle60->Location = System::Drawing::Point(906, 488);
			this->radioButton_angle60->Name = L"radioButton_angle60";
			this->radioButton_angle60->Size = System::Drawing::Size(78, 17);
			this->radioButton_angle60->TabIndex = 16;
			this->radioButton_angle60->TabStop = true;
			this->radioButton_angle60->Text = L"60 degrees";
			this->radioButton_angle60->UseVisualStyleBackColor = true;
			this->radioButton_angle60->CheckedChanged += gcnew System::EventHandler(this, &Form1::radioButton_angle60_CheckedChanged);
			// 
			// radioButton_angle90
			// 
			this->radioButton_angle90->AutoSize = true;
			this->radioButton_angle90->Location = System::Drawing::Point(998, 488);
			this->radioButton_angle90->Name = L"radioButton_angle90";
			this->radioButton_angle90->Size = System::Drawing::Size(78, 17);
			this->radioButton_angle90->TabIndex = 17;
			this->radioButton_angle90->TabStop = true;
			this->radioButton_angle90->Text = L"90 degrees";
			this->radioButton_angle90->UseVisualStyleBackColor = true;
			this->radioButton_angle90->CheckedChanged += gcnew System::EventHandler(this, &Form1::radioButton_angle90_CheckedChanged);
			// 
			// Form1
			// 
			this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
			this->BackgroundImage = (cli::safe_cast<System::Drawing::Image^  >(resources->GetObject(L"$this.BackgroundImage")));
			this->BackgroundImageLayout = System::Windows::Forms::ImageLayout::None;
			this->ClientSize = System::Drawing::Size(1092, 522);
			this->Controls->Add(this->radioButton_angle90);
			this->Controls->Add(this->radioButton_angle60);
			this->Controls->Add(this->radioButton_angle30);
			this->Controls->Add(this->radioButton_angle0);
			this->Controls->Add(this->Button_delete_last);
			this->Controls->Add(this->Angle_button);
			this->Controls->Add(this->button_clear_lines);
			this->Controls->Add(this->listBox_line_measurements);
			this->Controls->Add(this->label2);
			this->Controls->Add(this->textBox4);
			this->Controls->Add(this->label1);
			this->Controls->Add(this->textBox3);
			this->Controls->Add(this->textBox2);
			this->Controls->Add(this->textBox1);
			this->DoubleBuffered = true;
			this->Name = L"Form1";
			this->Text = L"Line Distance and Angle Simulator for Robot Paths";
			this->Load += gcnew System::EventHandler(this, &Form1::Form1_Load);
			this->MouseUp += gcnew System::Windows::Forms::MouseEventHandler(this, &Form1::Form1_MouseUp);
			this->Paint += gcnew System::Windows::Forms::PaintEventHandler(this, &Form1::Form1_Paint);
			this->MouseDown += gcnew System::Windows::Forms::MouseEventHandler(this, &Form1::Form1_MouseDown);
			this->MouseMove += gcnew System::Windows::Forms::MouseEventHandler(this, &Form1::Form1_MouseMove);
			this->ResumeLayout(false);
			this->PerformLayout();

		}
#pragma endregion
	private: System::Void Form1_Paint(System::Object^  sender, System::Windows::Forms::PaintEventArgs^  e) {
				 Graphics^ g = e->Graphics;
				 Pen^ pen1 = gcnew Pen(Color::DarkSlateBlue);
				 pen1->Width = 10;
				 Pen^ pen2 = gcnew Pen(Color::Aquamarine);
				 pen2->Width = 10;

				 Bitmap^ bmp1 = gcnew Bitmap("NXT_picture.jpg"); //construct a bitmap from file
				 bmp1->MakeTransparent();
				 
				 if (linecount > 0){
					int a = mouse_x - mx[linecount - 1];
					int b = mouse_y - my[linecount - 1];
					int c = 100;
					int d = 0;
					double frank1 = (a*a+b*b);
					double frank2 = (c*c+d*d);
				    double franksquare_root = sqrt(double (frank1))* sqrt(double (frank2));
					double z = ((a*c)+(b*d))/ franksquare_root;
					double angle_radians = acos(z); //Converting to angle
					double pivalue = 3.141592653589793l;
					double angle_degrees = angle_radians*180/pivalue;

					
					g->DrawLine(pen1,mx[linecount - 1],my[linecount - 1],mouse_x,mouse_y); //draw rubber band line
					for(int x = 1; x < linecount; x++){
						g->DrawLine(pen2,mx[x - 1],my[x - 1],mx[x],my[x]); //draw line segment
					}
					if(a != 0.0){
						g->TranslateTransform(mouse_x, mouse_y);
						if(b >= 0.0){
							g->RotateTransform(angle_degrees + 90.0);
							
						}
						else{
							 g->RotateTransform(90.0 - angle_degrees);
						}
						g->DrawImage(bmp1, -29, -55); //draws image
				       }
					}
				 else {
				 g->TranslateTransform(mouse_x, mouse_y);
				 g->RotateTransform(Robo_angle);
                 g->DrawImage(bmp1, -29, -55); //draws image
				 
				 }
			 }
private: System::Void Form1_MouseDown(System::Object^  sender, System::Windows::Forms::MouseEventArgs^  e) {
			 
			 if(linecount > 99)linecount = 0;
			 mx[linecount] = e->X;
			 my[linecount] = e->Y; //store current mouse possition
			 linecount++;
			 Invalidate();

		 }
private: System::Void Form1_MouseUp(System::Object^  sender, System::Windows::Forms::MouseEventArgs^  e) {

			 if(linecount > 1){ //makes program only display line measurement when there is actually a line
				 /*1 revolution = 225 degrees
                 1.360 revolutions = 360 degrees1*/

				  
				 
				
				 int a1 = mx[linecount - 1] - mx[linecount - 2]; //x axis pixel difference
				 int b1 = my[linecount - 1] - my[linecount - 2]; //y axis pixel difference
				 double csquared = a1 * a1 + b1 * b1; 
				 double c1 = sqrt( double(csquared)); //a squared + b squared = c squared
				 //String strRevperPixel = textBox4->Text;
				 double rev_length = c1 * 0.009910034;
				 double inch_length = c1 * 0.099009901;
				 

                 if(linecount > 2){ 
					double revs_per_degree = 1.36/360;
					int a = mx[linecount - 3] - mx[linecount - 2];
					int b = my[linecount - 3] - my[linecount - 2];
					int c = mx[linecount - 1] - mx[linecount - 2];
					int d = my[linecount - 1] - my[linecount - 2];
					double frank1 = (a*a+b*b);
					double frank2 = (c*c+d*d);
				    double franksquare_root = sqrt(double (frank1))* sqrt(double (frank2));
					double z = ((a*c)+(b*d))/ franksquare_root;
					double angle_radians = acos(z); //Converting to angle
					double pivalue = 3.141592653589793l;
					double angle_degrees =180.0 - angle_radians*180/pivalue; //convert to degerees, take compliment of angle
					textBox1->Text = c1.ToString("0.0"); //write length of line to text box 1
					double calculated_turn = revs_per_degree * angle_degrees;				 
					listBox_line_measurements->Items->Add("Angle =" + angle_degrees.ToString("0.0") + "Revs =" + calculated_turn.ToString("0.000"));
					Debug::WriteLine("b1 = " + b1.ToString("0.0"));
					Debug::WriteLine("c1 = " + c1.ToString("0.0"));
			 }
	             listBox_line_measurements->Items->Add("Line " + linecount.ToString("0.0") + "=" + c1.ToString("0.0") + " Pixels");
                 listBox_line_measurements->Items->Add("Line " + linecount.ToString("0.0") + "=" + inch_length.ToString("0.0") + " Inches");				
				 listBox_line_measurements->Items->Add("Line " + linecount.ToString("0.0") + "=" + rev_length.ToString("0.0") + " Revs");
				 Debug::WriteLine("a1 = " + a1.ToString("0.0"));
			 }
		 }
private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
		 }
private: System::Void Conversion_Button_Click(System::Object^  sender, System::EventArgs^  e) {
		 }
private: System::Void Form1_MouseMove(System::Object^  sender, System::Windows::Forms::MouseEventArgs^  e) {
			 mouse_x = e->X;
			 mouse_y = e->Y;
			 Invalidate();
		 }
private: System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e) {
		 }
private: System::Void button_clear_lines_Click(System::Object^  sender, System::EventArgs^  e) {
			 linecount = 0; //ressetimg linecount to erase lines
			 listBox_line_measurements->Items->Clear();
			 Invalidate();
		 }
private: System::Void listBox_line_measurements_SelectedIndexChanged(System::Object^  sender, System::EventArgs^  e) {
		 }
private: System::Void button1_Click_1(System::Object^  sender, System::EventArgs^  e) {
			 //calculate_angles
			 /*You may like this solution using dot products between two vectors.
			 Suppose you have two lines where the first line passes through the points (x1,y1), (x2,y2), 
			 and the second line passes through the points (x3,y3) and (x4,y4).
			 Take the differences between the x and y coordinates for both lines. 
			 a = x2 - x1, b = y2 - y1, c = x4 - x3, and d = y4 - y3. The so called dot product yields the equation
             Cosine( Theta ) = ( (a x c) + (b x d) )/(Sqrt(a^2 + b^2) x Sqrt(c^2 + d^2) ) = Z.
             The angle you'd be interested in is Theta or the angle between the two lines and that can be found 
			 using the inverse cosine or Theta = ArcCos( Z ) where of course Z is the somewhat complicated 
			 expression involving a,b,c,d. Probably be difficult for you to find a class that contains an interface 
			 that readily accomplish this for you. You could just code it up in alot less time. Hope you find this 
			 useful.
             */
			 int a = mx[linecount - 3] - mx[linecount - 2];
			 int b = my[linecount - 3] - my[linecount - 2];
			 int c = mx[linecount - 1] - mx[linecount - 2];
			 int d = my[linecount - 1] - my[linecount - 2];
             double frank1 = (a*a+b*b);
			 double frank2 = (c*c+d*d);
			 double franksquare_root = sqrt(double (frank1))* sqrt(double (frank2));
			 double z = ((a*c)+(b*d))/ franksquare_root;
			 double angle_radians = acos(z); //Converting to angle
			 double pivalue = 3.141592653589793l;
			 double angle_degrees = angle_radians*180/pivalue; //convert to degerees
			 textBox2->Text=angle_degrees.ToString("0.0"); 
			 

		 }
private: System::Void textBox4_TextChanged(System::Object^  sender, System::EventArgs^  e) {
		 }
private: System::Void Button_delete_last_Click(System::Object^  sender, System::EventArgs^  e) {

			 if(linecount > 0){
				 

				 for(int x = 0; x<4; x++){
					 int q = listBox_line_measurements->Items->Count;
					 if(q > 0) 
						listBox_line_measurements->Items->RemoveAt(q - 1);
					 
				 }
			 linecount--;
			 Invalidate();
		   }
		}
private: System::Void radioButton_angle0_CheckedChanged(System::Object^  sender, System::EventArgs^  e) {
			 Robo_angle = 0.0;
		 }
private: System::Void radioButton_angle30_CheckedChanged(System::Object^  sender, System::EventArgs^  e) {
			 Robo_angle = 30.0;
		 }
private: System::Void radioButton_angle60_CheckedChanged(System::Object^  sender, System::EventArgs^  e) {
			 Robo_angle = 60.0;
		 }
private: System::Void radioButton_angle90_CheckedChanged(System::Object^  sender, System::EventArgs^  e) {
			 Robo_angle = 90.0;
		 }
};
}

